﻿namespace Comet.View
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Comet.Presentation;
    using System.Windows.Forms;
using System.Drawing;
    using System.Resources;
    using Comet.Infrastructure;

    /// <summary>   
    ///     Represents a data member that can be displayed
    ///     in a list view.
    /// </summary>
    /// <remarks>   
    ///     Simon, 10.07.2010. 
    /// </remarks>
    public class DataMemberListViewItem : ListViewItem, IDataMemberView
    {
        #region Fields (6) 

        DataMemberType dataMemberType;
        DataMemberVisibility dataMemberVisibility;

        string name;
        DataMemberPresenter presenter;
        static string textTemplate = "{0}: {1}";
        string typeName;

        ListViewSubItem typeItem = new ListViewSubItem();

        #endregion Fields 

        #region Constructors (1) 

        /// <summary>   
        ///     Creates a new instance of the DataMemberListViewItem class. 
        /// </summary>
        /// <remarks>   
        ///     Simon, 10.07.2010. 
        /// </remarks>
        public DataMemberListViewItem(DataMemberPresenter presenter)
        {
            if (presenter == null)
            {
                throw new ArgumentNullException("presenter");
            }

            this.presenter = presenter;
            this.presenter.View = this;

            //initialize type column
            this.typeItem.ForeColor = SystemColors.GrayText;

            //Add item and specify that sub items want to use own style
            base.UseItemStyleForSubItems = false;
            base.SubItems.Add(typeItem);

            //update icon
            UpdateIcon();
        }

        #endregion Constructors 

        #region Properties (5) 

        /// <summary>   
        ///     Gets or sets the name of the data member
        ///     represented by this object.
        /// </summary>
        /// <value> 
        ///     The name. 
        /// </value>
        public string DataMemberName
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
                this.Text = value;
            }
        }

        /// <summary>   
        ///     Gets or sets the type of the data member. 
        /// </summary>
        /// <value> 
        ///     The type of the data member. 
        /// </value>
        public DataMemberType DataMemberType
        {
            get
            {
                return dataMemberType;
            }
            set
            {
                if (this.dataMemberType == value)
                    return;

                this.dataMemberType = value;

                UpdateIcon();
            }
        }

        public DataMemberVisibility DataMemberVisibility
        {
            get
            {
                return dataMemberVisibility;
            }
            set
            {
                if (dataMemberVisibility == value)
                {
                    return;
                }

                dataMemberVisibility = value;
                UpdateIcon();
            }
        }

        /// <summary>   
        ///     Gets or sets a value indicating whether this has been selected. 
        /// </summary>
        /// <value> 
        ///     true if this object is selected, false if not. 
        /// </value>
        /// 
        bool isSelected;
        public bool IsSelected
        {
            get
            {
                return isSelected;
            }
            set
            {
                if (value == this.isSelected)
                    return;

                this.isSelected = value;

                if (value != this.Checked)
                {
                    this.Checked = value;
                }

                if (this.isSelected)
                    RaiseSelectionGained(EventArgs.Empty);
                else
                    RaiseDeselected(EventArgs.Empty);
                
            }
        }

        /// <summary>   
        ///     Gets or sets the name of the type. 
        /// </summary>
        /// <value> 
        ///     The name of the type. 
        /// </value>
        public string TypeName
        {
            get
            {
                return typeName;
            }
            set
            {
                this.typeName = value;
                this.typeItem.Text = value;
            }
        }

        #endregion Properties 

        #region Delegates and Events (2) 

        // Events (2) 

        /// <summary> Event queue for all listeners interested in Deselected events. </summary>
        public event EventHandler Deselected = delegate { };

        /// <summary> Event queue for all listeners interested in SelectionGained events. </summary>
        public event EventHandler SelectionGained = delegate { };

        #endregion Delegates and Events 

        #region Methods (3) 

        // Private Methods (3) 

        /// <summary>   
        ///     Raises the deselected event. 
        /// </summary>
        /// <remarks>   
        ///     Simon, 10.07.2010. 
        /// </remarks>
        /// <param name="e">    Event information to send to registered event handlers. </param>
        void RaiseDeselected(EventArgs e)
        {
            Deselected(this, e);
        }

        /// <summary>   
        ///     Raises the selected event. 
        /// </summary>
        /// <remarks>   
        ///     Simon, 10.07.2010. 
        /// </remarks>
        /// <param name="e">    Event information to send to registered event handlers. </param>
        void RaiseSelectionGained(EventArgs e)
        {
            SelectionGained(this, e);
        }

        private void UpdateIcon()
        {
            ImageIndex = icons[this.dataMemberType][this.dataMemberVisibility];
        }

        #endregion Methods 



        #region Static Members

        static Dictionary<DataMemberType, Dictionary<DataMemberVisibility, int>> icons = new Dictionary<DataMemberType, Dictionary<DataMemberVisibility, int>>();
        
        static DataMemberListViewItem()
        {
            Dictionary<DataMemberVisibility, int> propertyImages = new Dictionary<DataMemberVisibility, int>();
            propertyImages[DataMemberVisibility.PublicAccess] = 6;
            propertyImages[DataMemberVisibility.InternalAccess] = 10;
            propertyImages[DataMemberVisibility.ProtectedAccess] = 9;
            propertyImages[DataMemberVisibility.PrivateAccess] = 8;

            Dictionary<DataMemberVisibility, int> fieldImages = new Dictionary<DataMemberVisibility, int>();
            fieldImages[DataMemberVisibility.PublicAccess] = 0;
            fieldImages[DataMemberVisibility.InternalAccess] = 4;
            fieldImages[DataMemberVisibility.ProtectedAccess] = 3;
            fieldImages[DataMemberVisibility.PrivateAccess] = 2;

            icons[DataMemberType.Property] = propertyImages;
            icons[DataMemberType.Field] = fieldImages;
        }

        #endregion
    }
}
